Skip to content

BigQuery: Parse WITH CONNECTION on CREATE EXTERNAL TABLE#2326

Open
97nitt wants to merge 4 commits intoapache:mainfrom
97nitt:upstream/bigquery-external-table-connection-options
Open

BigQuery: Parse WITH CONNECTION on CREATE EXTERNAL TABLE#2326
97nitt wants to merge 4 commits intoapache:mainfrom
97nitt:upstream/bigquery-external-table-connection-options

Conversation

@97nitt
Copy link
Copy Markdown

@97nitt 97nitt commented Apr 28, 2026

Summary

Parse the WITH CONNECTION <name> clause on BigQuery CREATE EXTERNAL TABLE
statements. Per the BigQuery DDL reference, external tables (and
external Iceberg tables in particular) carry a connection identifier between
the column list and the OPTIONS(...) clause:

CREATE OR REPLACE EXTERNAL TABLE `proj.ds.tbl`
WITH CONNECTION `projects/proj/locations/us/connections/c`
OPTIONS(format = "ICEBERG", uris = ["gs://b/m.json"]);

Today the parser rejects this shape because nothing consumes WITH CONNECTION,
and OPTIONS(...) on external tables only worked via the Hive
TBLPROPERTIES fallback path.

Changes

  • CreateTable / CreateTableBuilder: new with_connection: Option<ObjectName>
    field, populated by the parser and rendered by Display between
    CLUSTER BY and OPTIONS(...).
  • parse_create_external_table: consume an optional WITH CONNECTION <name>,
    then prefer OPTIONS(...) over TBLPROPERTIES(...) (mutually exclusive in
    practice; preserves the existing Hive path when neither is present).
  • Tests: new BigQuery cases covering WITH CONNECTION with OPTIONS,
    WITH CONNECTION alone (Display normalizes by adding an empty column list),
    the (columns) WITH CONNECTION OPTIONS(...) round-trip, and a baseline
    that asserts with_connection stays None when the keyword pair is absent.
  • tests/sqlparser_duckdb.rs, tests/sqlparser_mssql.rs,
    tests/sqlparser_postgres.rs: updated existing struct-literal expectations
    for the new field.

Test plan

  • cargo test
  • cargo fmt --check
  • cargo clippy --all-targets --all-features -- -D warnings

Comment thread src/ast/helpers/stmt_create_table.rs Outdated
Comment on lines +160 to +161
/// BigQuery `WITH CONNECTION` clause for external tables.
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// BigQuery `WITH CONNECTION` clause for external tables.
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement>
/// `WITH CONNECTION` clause.
/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread src/ast/helpers/stmt_create_table.rs Outdated
self.external_volume = external_volume;
self
}
/// Set the BigQuery `WITH CONNECTION` clause for external tables.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Set the BigQuery `WITH CONNECTION` clause for external tables.
/// Set the `WITH CONNECTION` clause.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread src/ast/ddl.rs Outdated
Comment on lines +3024 to +3025
/// BigQuery `WITH CONNECTION` clause for external tables
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// BigQuery `WITH CONNECTION` clause for external tables
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement>
/// `WITH CONNECTION` clause.
/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_external_table_statement)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread src/parser/mod.rs Outdated
Comment on lines +6420 to +6421
// BigQuery external tables support `WITH CONNECTION <name>` and `OPTIONS(...)`
// clauses after the (optional) column list.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// BigQuery external tables support `WITH CONNECTION <name>` and `OPTIONS(...)`
// clauses after the (optional) column list.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread src/parser/mod.rs Outdated
Comment on lines +6427 to +6432
// BigQuery uses OPTIONS(...); Hive uses TBLPROPERTIES(...). They are
// mutually exclusive in practice, and `parse_options` returns an empty
// vec when the keyword isn't present, so trying OPTIONS first and
// falling back to TBLPROPERTIES preserves the existing Hive path
// without accepting both in the same statement.
let options = self.parse_options(Keyword::OPTIONS)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I follow the goal here, is OPTIONS part of the WITH CONNECTION clause (if not isn't it already parsed elsewhere for bigquery today)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, reverted. The parser change is now just the new WITH CONNECTION block plus the .with_connection(...) builder line; the fallback chain handles OPTIONS unchanged.

Comment thread tests/sqlparser_bigquery.rs Outdated
};
assert_eq!(opts.len(), 1);

// Baseline: no WITH CONNECTION. The new parser branch must not produce
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove these superfluous comments from the tests

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread tests/sqlparser_bigquery.rs Outdated
"WITH CONNECTION `projects/proj/locations/us/connections/c` ",
r#"OPTIONS(format = "ICEBERG", uris = ["gs://b/m.json"])"#,
);
let stmts = bigquery().parse_sql_statements(sql).unwrap();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the tests is there a reason we don't use verified_stmt? Also I think we can skip the assertions on the ast and have it solely as roundtrip tests (I don't think the ast assertions are adding much given the changes made and preexisting tests)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

97nitt added 3 commits April 29, 2026 09:24
The pre-existing maybe_parse_options(OPTIONS) fallback already
handled BigQuery OPTIONS(...) on external tables; the reorder
made it unreachable without changing behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants